#include "ContactStorage.h"
#include "ContactException.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;


void ContactStorage::saveContact(const add_contact_req::AddContactRequest& contact,const string& uid)
{
     // 打开文件，如果没有则创建，追加内容
     std::ofstream ofs(dbFile,std::ios::app);

     if(!ofs.is_open())
     {
        DEBUG_LOG("无法打开联系人文件");
        return;
     }

        // 写入联系人信息 (UTF-8 文本)
     ofs << "姓名: " << contact.name() << std::endl;
     ofs << "Uid: "  << uid << std::endl;
     ofs << "年龄: " << contact.age() << std::endl;
     ofs << "电话: " << std::endl;

    // 写入电话号码
     for (int i = 0; i < contact.phone_size(); i++) 
     {
         ofs << "  电话" << (i + 1) << ": " << contact.phone(i).number() << std::endl;
     }

     ofs << "-----------------------------------------" << std::endl; // 分隔符
     ofs.close();
}

bool ContactStorage::deleteContact(const std::string& uid) 
{
    std::ifstream ifs(dbFile);
    if (!ifs.is_open()) 
        return false;
    
    std::ofstream ofs("contacts_tmp.txt", std::ios::trunc);
    if (!ofs.is_open()) 
        return false;
    
        
    bool found = false;
    bool skipBlock = false;
    std::string buffer; // 暂存当前联系人
    std::string line;
    while(std::getline(ifs,line))
    {
        // 如果是一个新联系人的开始
        if (line.rfind("姓名:", 0) == 0) {
            // 处理上一个联系人（如果不是目标 uid，则写回文件）
            if (!buffer.empty() && !skipBlock) {
                ofs << buffer;
            }
            buffer.clear();
            skipBlock = false; // 默认不过滤
        }

        // 缓存当前行
        buffer += line + "\n";

        // 检查是否包含要删除的 Uid
        if (line.find("Uid: " + uid) != std::string::npos) {
            found = true;
            skipBlock = true; // 标记整块要删除
        }
    }

    // 处理最后一个联系人
    if (!buffer.empty() && !skipBlock) {
        ofs << buffer;
    }

    ifs.close();
    ofs.close();

    if (found) 
    {
        std::remove(dbFile.c_str());
        std::rename("contacts_tmp.txt", dbFile.c_str());
    } 
    else
    {
        std::remove("contacts_tmp.txt");
    }

    return found;

}


// trim 工具函数（去掉前后空格、换行、制表符、BOM）
static inline std::string trim(const std::string& s)
{
    size_t start = s.find_first_not_of(" \t\n\r\0\xEF\xBB\xBF");
    size_t end   = s.find_last_not_of(" \t\n\r\0");
    if (start == std::string::npos)
    {
        return "";
    }
    return s.substr(start, end - start + 1);
}

bool ContactStorage::findContactByName(const std::string& name,
                                       add_contact_req::AddContactRequest& out,
                                       std::string& uid)
{
    std::ifstream ifs(dbFile);
    if (!ifs.is_open())
    {
        DEBUG_LOG("无法打开联系人文件: " + dbFile);
        return false;
    }

    std::string line;
    std::string curName, curUid;
    int curAge = 0;
    std::vector<std::string> phones;

    auto trim = [](std::string& s) {
        s.erase(0, s.find_first_not_of(" \t\r\n"));
        s.erase(s.find_last_not_of(" \t\r\n") + 1);
    };

    while (std::getline(ifs, line))
    {
        if (line.rfind("姓名: ", 0) == 0)
        {
            curName = line.substr(strlen("姓名: "));
            trim(curName);
            DEBUG_LOG("读取姓名: " + curName);
        }
        else if (line.rfind("Uid: ", 0) == 0)
        {
            curUid = line.substr(strlen("Uid: "));
            trim(curUid);
            DEBUG_LOG("读取Uid: " + curUid);
        }
        else if (line.rfind("年龄: ", 0) == 0)
        {
            std::string ageStr = line.substr(strlen("年龄: "));
            trim(ageStr);
            try
            {
                curAge = std::stoi(ageStr);
                DEBUG_LOG("读取年龄: " + std::to_string(curAge));
            }
            catch (...)
            {
                DEBUG_LOG("年龄字段解析失败: " + ageStr);
                curAge = 0;
            }
        }
        else if (line.find("电话") != std::string::npos) // 匹配 "电话:" 或 "电话1: "
        {
            size_t pos = line.find(":");
            if (pos != std::string::npos)
            {
                std::string phone = line.substr(pos + 1);
                trim(phone);
                if (!phone.empty())
                {
                    phones.push_back(phone);
                    DEBUG_LOG("读取电话: " + phone);
                }
            }
        }
        else if (line.find("---") != std::string::npos) // 分隔符 -> 一个联系人结束
        {
            if (curName == name)  // 找到目标
            {
                out.set_name(curName);
                out.set_age(curAge);
                uid = curUid;
                for (auto& p : phones)
                {
                    auto phonePtr = out.add_phone();
                    phonePtr->set_number(p);
                }
                return true;
            }
            // 清空，继续下一个联系人
            curName.clear();
            curUid.clear();
            curAge = 0;
            phones.clear();
        }
    }

    return false;
}


bool ContactStorage::findAllContacts(std::vector<add_contact_req::AddContactRequest>& outList,
                                     std::vector<std::string>& uids)
{
    std::ifstream ifs(dbFile);
    if (!ifs.is_open())
    {
        DEBUG_LOG("无法打开联系人文件: " + dbFile);
        return false;
    }

    std::string line;
    std::string curName, curUid;
    int curAge = 0;
    std::vector<std::string> phones;

    auto flushContact = [&]()
    {
        if (!curName.empty() && !curUid.empty())
        {
            add_contact_req::AddContactRequest contact;
            contact.set_name(curName);
            contact.set_age(curAge);
            for (auto& p : phones)
            {
                auto ph = contact.add_phone();
                ph->set_number(p);
            }
            outList.push_back(contact);
            uids.push_back(curUid);
        }
        curName.clear();
        curUid.clear();
        curAge = 0;
        phones.clear();
    };

    while (std::getline(ifs, line))
    {
        if (line.rfind("姓名:", 0) == 0)
        {
            flushContact();
            curName = line.substr(7);
        }
        else if (line.rfind("Uid:", 0) == 0)
        {
            curUid = line.substr(5);
        }
        else if (line.rfind("年龄:", 0) == 0)
        {
            try
            {
                curAge = std::stoi(line.substr(7));
            }
            catch (...)
            {
                DEBUG_LOG("年龄字段解析失败: " + line);
                curAge = 0;
            }
        }
        else if (line.rfind("电话", 0) == 0)
        {
            std::string phoneLine = line.substr(line.find(":") + 1);
            if (!phoneLine.empty())
            {
                phones.push_back(phoneLine);
            }
        }
    }

    flushContact();
    return !outList.empty();
}
